#!/usr/bin/env python
# -*- coding: utf-8 -*-

from PyQt4.QtCore       import *
from PyQt4.QtGui        import *
from predecode          import PreDecodeThread

import os
import sys
import os.path
import time

class MyScrollArea(QScrollArea):
    def __init__(self):
        QScrollArea.__init__(self)

    def keyPressEvent(self, event):
        event.ignore()

class MainWindow(QMainWindow):
    """
    """
    
    def __init__(self):
        """
        """
        QMainWindow.__init__(self)

        self.image_label = QLabel()
        self.scale_factor = 1.0

        self.image_scroll_area = MyScrollArea()
        self.image_scroll_area.setBackgroundRole(QPalette.Dark)
        self.image_scroll_area.setAlignment(Qt.AlignHCenter | Qt.AlignVCenter)

        self.image_scroll_area.setWidgetResizable(True)

        # the options is
        #   factor
        #   fixed
        self.scale_type = 'factor'

        self.image_scroll_area.setWidget(self.image_label)

        self.setCentralWidget(self.image_scroll_area)

        self.resize(800, 600)

        self.load_thread = PreDecodeThread()

        self.load_thread.start()

        self.file_name_list = []
        self.curr_index = 0

        if sys.platform.startswith('win'):
            self.coding = "gbk"
        else:
            self.coding = "utf8"

    def _exit(self, code):
        """
        
        Arguments:
        - `code`:
        """
        self.load_thread.terminate()
        QApplication.exit(code)
        
    def set_title(self, title):
        """
        
        Arguments:
        - `title`:
        """
        self.setWindowTitle(title)

    def _show_curr_image(self):
        """
        """
        # prev_get = time.time()
        image = self.load_thread.get_image(self.curr_index)
        # diff = time.time() - prev_get
        # print "%f seconds to get image" % diff
        # print "show %d" % self.curr_index
        if image is not None:
            if self.scale_type == 'fixed':
                size = self.image_scroll_area.size()
                if image.width() > size.width() or image.height() > size.height():
                    image = image.scaled(self.image_scroll_area.size(), Qt.KeepAspectRatio)

            self.image_label.setPixmap(QPixmap.fromImage(image))

            self.set_title(self.file_name_list[self.curr_index])
        else:
            assert "can't get image" and False

    def next_image(self):
        if len(self.file_name_list) > 0:
            self.curr_index += 1
            if self.curr_index >= len(self.file_name_list):
                self.curr_index = 0
            self._show_curr_image()

    def prev_image(self):
        if len(self.file_name_list) > 0:
            self.curr_index -= 1
            if self.curr_index < 0:
                self.curr_index = len(self.file_name_list) - 1
            self._show_curr_image()

    def _is_image_fn(self, fn):
        lower = fn.lower()
        if lower.endswith(".jpg") or lower.endswith(".png"):
            return True
        else:
            return False

    def set_image(self, fn):
        """
        
        Arguments:
        - `fn`:
        """

        if type(fn) != unicode:
            fn = unicode(fn)

        # change the directory
        dname = os.path.dirname(fn)
        if dname and dname != u'.':
            if not os.path.isdir(dname):
                print "%s is not directory." % dname
                self._exit(1)
            try:
                os.chdir(dname)
            except:
                print "change directory to %s failed" % dname
                self._exit(1)

        found_images = []
        for t in os.listdir("."):
            if self._is_image_fn(t):
                found_images.append(unicode(t, self.coding))

        if len(found_images) == 0:
            return False

        self.file_name_list = found_images

        self.load_thread.change_file_name_list(found_images)

        bname = os.path.basename(fn)
        try:
            idx = found_images.index(bname)
        except:
            idx = 0
        self.curr_index = idx

        self._show_curr_image()

        return True

    def keyPressEvent(self, event):
        k = event.key()
        if k == Qt.Key_PageDown or k == Qt.Key_Down:
            self.next_image()
        elif k == Qt.Key_PageUp or k == Qt.Key_Up:
            self.prev_image()
        elif k == Qt.Key_F:
            if self.scale_type == 'factor':
                self.scale_type = 'fixed'
            else:
                self.scale_type = 'factor'
            self._show_curr_image()
        elif k == Qt.Key_O:
            fileName = QFileDialog.getOpenFileName(self,
                                                   u"Open Image",
                                                   os.getcwd(),
                                                   u"Image Files (*.png *.jpg)")
            if fileName:
                ufn = unicode(fileName.toAscii().data(), "utf8")
                self.set_image(ufn)
        elif k == Qt.Key_Escape:
            self._exit(0)
